package com.uniflow.service;

import com.uniflow.entity.RolePermission;
import com.uniflow.mapper.RolePermissionMapper;
import com.uniflow.util.AuditLogHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 角色权限关联服务层
 * 
 * @author luban
 * @since 1.0.0
 */
@Service
@Transactional
public class RolePermissionService {
    
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    
    @Autowired
    private AuditLogHelper auditLogHelper;
    
    /**
     * 根据ID查询角色权限关联
     */
    public RolePermission getRolePermissionById(String id) {
        return rolePermissionMapper.selectById(id);
    }
    
    /**
     * 根据角色ID查询权限关联列表
     */
    public List<RolePermission> getRolePermissions(String roleId) {
        return rolePermissionMapper.selectByRoleId(roleId);
    }
    
    /**
     * 根据权限ID查询角色关联列表
     */
    public List<RolePermission> getPermissionRoles(String permissionId) {
        return rolePermissionMapper.selectByPermissionId(permissionId);
    }
    
    /**
     * 检查角色是否有指定权限
     */
    public boolean hasRolePermission(String roleId, String permissionId) {
        return rolePermissionMapper.hasRolePermission(roleId, permissionId);
    }
    
    /**
     * 检查角色是否被授权指定权限
     */
    public boolean isRolePermissionGranted(String roleId, String permissionId) {
        return rolePermissionMapper.isRolePermissionGranted(roleId, permissionId);
    }
    
    /**
     * 查询角色的权限ID列表
     */
    public List<String> getRolePermissionIds(String roleId) {
        return rolePermissionMapper.selectPermissionIdsByRoleId(roleId);
    }
    
    /**
     * 查询角色的已授权权限ID列表
     */
    public List<String> getGrantedPermissionIds(String roleId) {
        return rolePermissionMapper.selectGrantedPermissionIdsByRoleId(roleId);
    }
    
    /**
     * 查询权限的角色ID列表
     */
    public List<String> getPermissionRoleIds(String permissionId) {
        return rolePermissionMapper.selectRoleIdsByPermissionId(permissionId);
    }
    
    /**
     * 为角色分配权限
     */
    @Transactional
    public RolePermission grantPermission(String roleId, String permissionId, String operatorId, String operatorName) {
        return grantPermission(roleId, permissionId, true, operatorId, operatorName);
    }
    
    /**
     * 为角色分配权限（指定授权状态）
     */
    @Transactional
    public RolePermission grantPermission(String roleId, String permissionId, Boolean granted, String operatorId, String operatorName) {
        // 检查是否已存在
        RolePermission existing = rolePermissionMapper.selectByRoleIdAndPermissionId(roleId, permissionId);
        if (existing != null) {
            // 如果已存在，更新授权状态
            if (!existing.getGranted().equals(granted)) {
                existing.setGranted(granted);
                rolePermissionMapper.updateById(existing);
                
                // 记录审计日志
                auditLogHelper.recordLog(
                    granted ? "GRANT_PERMISSION" : "REVOKE_PERMISSION",
                    "role_permission",
                    roleId + "-" + permissionId,
                    (granted ? "授权" : "撤销") + "角色权限",
                    "success",
                    operatorId
                );
            }
            return existing;
        }
        
        // 创建新的权限关联
        RolePermission rolePermission = new RolePermission(roleId, permissionId, granted);
        rolePermission.setId(UUID.randomUUID().toString().replace("-", ""));
        rolePermission.setCreatedBy(operatorId);
        rolePermission.setCreatedByName(operatorName);
        rolePermission.setCreatedAt(LocalDateTime.now());
        
        rolePermissionMapper.insert(rolePermission);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            granted ? "GRANT_PERMISSION" : "REVOKE_PERMISSION",
            "role_permission",
            roleId + "-" + permissionId,
            (granted ? "授权" : "撤销") + "角色权限",
            "success",
            operatorId
        );
        
        return rolePermission;
    }
    
    /**
     * 撤销角色权限
     */
    @Transactional
    public void revokePermission(String roleId, String permissionId, String operatorId) {
        grantPermission(roleId, permissionId, false, operatorId, null);
    }
    
    /**
     * 删除角色权限关联
     */
    @Transactional
    public void removePermission(String roleId, String permissionId, String operatorId) {
        // 检查是否存在
        if (!hasRolePermission(roleId, permissionId)) {
            throw new RuntimeException("角色权限关联不存在");
        }
        
        rolePermissionMapper.deleteByRoleIdAndPermissionId(roleId, permissionId);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "REMOVE_PERMISSION",
            "role_permission",
            roleId + "-" + permissionId,
            "删除角色权限关联",
            "success",
            operatorId
        );
    }
    
    /**
     * 批量为角色分配权限
     */
    @Transactional
    public void grantPermissions(String roleId, List<String> permissionIds, String operatorId, String operatorName) {
        for (String permissionId : permissionIds) {
            grantPermission(roleId, permissionId, operatorId, operatorName);
        }
    }
    
    /**
     * 批量撤销角色权限
     */
    @Transactional
    public void revokePermissions(String roleId, List<String> permissionIds, String operatorId) {
        for (String permissionId : permissionIds) {
            revokePermission(roleId, permissionId, operatorId);
        }
    }
    
    /**
     * 更新角色的所有权限
     */
    @Transactional
    public void updateRolePermissions(String roleId, List<String> permissionIds, String operatorId, String operatorName) {
        // 先删除角色的所有权限
        rolePermissionMapper.deleteByRoleId(roleId);
        
        // 再分配新权限
        if (permissionIds != null && !permissionIds.isEmpty()) {
            grantPermissions(roleId, permissionIds, operatorId, operatorName);
        }
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "UPDATE_ROLE_PERMISSIONS",
            "role",
            roleId,
            "更新角色权限，新权限数量: " + (permissionIds != null ? permissionIds.size() : 0),
            "success",
            operatorId
        );
    }
    
    /**
     * 删除角色的所有权限
     */
    @Transactional
    public void removeAllRolePermissions(String roleId, String operatorId) {
        int deletedCount = rolePermissionMapper.deleteByRoleId(roleId);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "REMOVE_ALL_PERMISSIONS",
            "role",
            roleId,
            "移除角色的所有权限，共移除: " + deletedCount + " 个权限",
            "success",
            operatorId
        );
    }
    
    /**
     * 删除权限的所有角色关联
     */
    @Transactional
    public void removeAllPermissionRoles(String permissionId, String operatorId) {
        int deletedCount = rolePermissionMapper.deleteByPermissionId(permissionId);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "REMOVE_PERMISSION_ROLES",
            "permission",
            permissionId,
            "移除权限的所有角色关联，共移除: " + deletedCount + " 个角色",
            "success",
            operatorId
        );
    }
    
    /**
     * 查询角色权限关联总数
     */
    public Long getTotalCount() {
        return rolePermissionMapper.selectCount();
    }
    
    /**
     * 查询指定角色的权限数量
     */
    public Long getRolePermissionCount(String roleId) {
        return rolePermissionMapper.selectRolePermissionCount(roleId);
    }
    
    /**
     * 查询指定权限的角色数量
     */
    public Long getPermissionRoleCount(String permissionId) {
        return rolePermissionMapper.selectPermissionRoleCount(permissionId);
    }
    
    /**
     * 查询权限分布统计
     */
    public List<Map<String, Object>> getPermissionDistributionStats() {
        return rolePermissionMapper.selectPermissionDistributionStats();
    }
    
    /**
     * 查询角色权限统计
     */
    public List<Map<String, Object>> getRolePermissionStats() {
        return rolePermissionMapper.selectRolePermissionStats();
    }
    
    /**
     * 查询最近分配的权限
     */
    public List<RolePermission> getRecentAssigned(Integer limit) {
        return rolePermissionMapper.selectRecentAssigned(limit);
    }
    
    /**
     * 查询指定时间段内的权限分配记录
     */
    public List<RolePermission> getAssignedInPeriod(LocalDateTime startTime, LocalDateTime endTime) {
        return rolePermissionMapper.selectAssignedInPeriod(startTime, endTime);
    }
    
    /**
     * 查询没有权限的角色列表
     */
    public List<String> getRolesWithoutPermission() {
        return rolePermissionMapper.selectRolesWithoutPermission();
    }
    
    /**
     * 查询没有角色的权限列表
     */
    public List<String> getPermissionsWithoutRole() {
        return rolePermissionMapper.selectPermissionsWithoutRole();
    }
    
    /**
     * 查询角色权限变更历史
     */
    public List<Map<String, Object>> getRolePermissionHistory(String roleId) {
        return rolePermissionMapper.selectRolePermissionHistory(roleId);
    }
    
    /**
     * 查询权限分配者统计
     */
    public List<Map<String, Object>> getAssignerStats() {
        return rolePermissionMapper.selectAssignerStats();
    }
    
    /**
     * 检查权限分配冲突
     */
    public List<Map<String, Object>> checkPermissionConflicts(String roleId, List<String> permissionIds) {
        return rolePermissionMapper.checkPermissionConflicts(roleId, permissionIds);
    }
    
    /**
     * 查询角色继承的权限
     */
    public List<RolePermission> getInheritedPermissions(String roleId) {
        return rolePermissionMapper.selectInheritedPermissions(roleId);
    }
    
    /**
     * 查询权限授权链
     */
    public List<Map<String, Object>> getPermissionAuthChain(String permissionId) {
        return rolePermissionMapper.selectPermissionAuthChain(permissionId);
    }
    
    /**
     * 复制角色权限
     */
    @Transactional
    public void copyRolePermissions(String sourceRoleId, String targetRoleId, String operatorId, String operatorName) {
        // 获取源角色的权限
        List<String> sourcePermissionIds = getGrantedPermissionIds(sourceRoleId);
        
        if (sourcePermissionIds.isEmpty()) {
            throw new RuntimeException("源角色没有任何权限");
        }
        
        // 为目标角色分配相同权限
        updateRolePermissions(targetRoleId, sourcePermissionIds, operatorId, operatorName);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "COPY_ROLE_PERMISSIONS",
            "role",
            targetRoleId,
            "从角色 " + sourceRoleId + " 复制权限到角色 " + targetRoleId + "，共复制 " + sourcePermissionIds.size() + " 个权限",
            "success",
            operatorId
        );
    }
    
    /**
     * 交换角色权限
     */
    @Transactional
    public void swapRolePermissions(String roleId1, String roleId2, String operatorId, String operatorName) {
        // 获取两个角色的权限
        List<String> role1PermissionIds = getGrantedPermissionIds(roleId1);
        List<String> role2PermissionIds = getGrantedPermissionIds(roleId2);
        
        // 交换权限
        updateRolePermissions(roleId1, role2PermissionIds, operatorId, operatorName);
        updateRolePermissions(roleId2, role1PermissionIds, operatorId, operatorName);
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "SWAP_ROLE_PERMISSIONS",
            "role",
            roleId1 + "-" + roleId2,
            "交换角色 " + roleId1 + " 和角色 " + roleId2 + " 的权限",
            "success",
            operatorId
        );
    }
    
    /**
     * 合并角色权限
     */
    @Transactional
    public void mergeRolePermissions(String sourceRoleId, String targetRoleId, String operatorId, String operatorName) {
        // 获取源角色和目标角色的权限
        List<String> sourcePermissionIds = getGrantedPermissionIds(sourceRoleId);
        List<String> targetPermissionIds = getGrantedPermissionIds(targetRoleId);
        
        // 合并权限（去重）
        for (String permissionId : sourcePermissionIds) {
            if (!targetPermissionIds.contains(permissionId)) {
                grantPermission(targetRoleId, permissionId, operatorId, operatorName);
            }
        }
        
        // 记录审计日志
        auditLogHelper.recordLog(
            "MERGE_ROLE_PERMISSIONS",
            "role",
            targetRoleId,
            "将角色 " + sourceRoleId + " 的权限合并到角色 " + targetRoleId,
            "success",
            operatorId
        );
    }
}